package ixOrm

import (
	"context"
	"fmt"
	"time"
)

// QueryBuilder 查询构建器
type QueryBuilder struct {
	tableOp       *TableOperator
	conditions    map[string]interface{}
	orConditions  []map[string]interface{} // OR 条件组
	rawConditions []RawCondition           // 原始 SQL 条件
	orderBy       []string
	groupBy       []string
	limit         int
	offset        int
	selectCols    []string
	useCache      bool
	cacheType     CacheType
	cacheKey      string
	cacheTTL      time.Duration
	context       context.Context
}

// Where 添加查询条件
func (t *TableOperator) Where(field string, value interface{}) *QueryBuilder {
	qb := &QueryBuilder{
		tableOp:    t,
		conditions: map[string]interface{}{field: value}, // 直接初始化，避免额外分配
		context:    context.Background(),
		useCache:   t.useCache,
		cacheType:  CacheTypeRedis, // 默认使用Redis缓存
		cacheKey:   t.cacheKey,
		cacheTTL:   t.cacheTTL,
	}
	return qb
}

// WhereIn 添加IN查询条件
func (t *TableOperator) WhereIn(field string, values []interface{}) *QueryBuilder {
	qb := &QueryBuilder{
		tableOp:    t,
		conditions: map[string]interface{}{field + " IN": values}, // 直接初始化
		context:    context.Background(),
		useCache:   t.useCache,
		cacheType:  CacheTypeRedis, // 默认使用Redis缓存
		cacheKey:   t.cacheKey,
		cacheTTL:   t.cacheTTL,
	}
	return qb
}

// WhereLike 添加LIKE查询条件
func (t *TableOperator) WhereLike(field string, pattern string) *QueryBuilder {
	qb := &QueryBuilder{
		tableOp:    t,
		conditions: map[string]interface{}{field + " LIKE": pattern},
		context:    context.Background(),
		useCache:   t.useCache,
		cacheType:  CacheTypeRedis,
		cacheKey:   t.cacheKey,
		cacheTTL:   t.cacheTTL,
	}
	return qb
}

// WhereNull 添加IS NULL查询条件
func (t *TableOperator) WhereNull(field string) *QueryBuilder {
	qb := &QueryBuilder{
		tableOp:       t,
		conditions:    make(map[string]interface{}, 4),
		rawConditions: []RawCondition{{SQL: field + " IS NULL", Values: nil}},
		context:       context.Background(),
		useCache:      t.useCache,
		cacheType:     CacheTypeRedis,
		cacheKey:      t.cacheKey,
		cacheTTL:      t.cacheTTL,
	}
	return qb
}

// WhereNotNull 添加IS NOT NULL查询条件
func (t *TableOperator) WhereNotNull(field string) *QueryBuilder {
	qb := &QueryBuilder{
		tableOp:       t,
		conditions:    make(map[string]interface{}, 4),
		rawConditions: []RawCondition{{SQL: field + " IS NOT NULL", Values: nil}},
		context:       context.Background(),
		useCache:      t.useCache,
		cacheType:     CacheTypeRedis,
		cacheKey:      t.cacheKey,
		cacheTTL:      t.cacheTTL,
	}
	return qb
}

// WhereBetween 添加BETWEEN查询条件
func (t *TableOperator) WhereBetween(field string, start, end interface{}) *QueryBuilder {
	qb := &QueryBuilder{
		tableOp:    t,
		conditions: make(map[string]interface{}, 4),
		rawConditions: []RawCondition{{
			SQL:    field + " BETWEEN ? AND ?",
			Values: []interface{}{start, end},
		}},
		context:   context.Background(),
		useCache:  t.useCache,
		cacheType: CacheTypeRedis,
		cacheKey:  t.cacheKey,
		cacheTTL:  t.cacheTTL,
	}
	return qb
}

// WhereRaw 添加原始SQL查询条件
func (t *TableOperator) WhereRaw(sql string, values ...interface{}) *QueryBuilder {
	qb := &QueryBuilder{
		tableOp:    t,
		conditions: make(map[string]interface{}, 4),
		rawConditions: []RawCondition{{
			SQL:    sql,
			Values: values,
		}},
		context:   context.Background(),
		useCache:  t.useCache,
		cacheType: CacheTypeRedis,
		cacheKey:  t.cacheKey,
		cacheTTL:  t.cacheTTL,
	}
	return qb
}

// Query 创建查询构建器
func (t *TableOperator) Query() *QueryBuilder {
	return &QueryBuilder{
		tableOp:    t,
		conditions: make(map[string]interface{}, 4), // 预分配容量
		context:    context.Background(),
		useCache:   t.useCache,
		cacheType:  CacheTypeRedis, // 默认使用Redis缓存
		cacheKey:   t.cacheKey,
		cacheTTL:   t.cacheTTL,
	}
}

// Where 添加查询条件
func (qb *QueryBuilder) Where(field string, value interface{}) *QueryBuilder {
	qb.conditions[field] = value
	return qb
}

// WhereIn 添加IN查询条件
func (qb *QueryBuilder) WhereIn(field string, values []interface{}) *QueryBuilder {
	qb.conditions[field+" IN"] = values
	return qb
}

// WhereLike 添加LIKE查询条件
func (qb *QueryBuilder) WhereLike(field string, pattern string) *QueryBuilder {
	qb.conditions[field+" LIKE"] = pattern
	return qb
}

// WhereNull 添加IS NULL查询条件
func (qb *QueryBuilder) WhereNull(field string) *QueryBuilder {
	qb.rawConditions = append(qb.rawConditions, RawCondition{
		SQL:    field + " IS NULL",
		Values: nil,
	})
	return qb
}

// WhereNotNull 添加IS NOT NULL查询条件
func (qb *QueryBuilder) WhereNotNull(field string) *QueryBuilder {
	qb.rawConditions = append(qb.rawConditions, RawCondition{
		SQL:    field + " IS NOT NULL",
		Values: nil,
	})
	return qb
}

// WhereBetween 添加BETWEEN查询条件
func (qb *QueryBuilder) WhereBetween(field string, start, end interface{}) *QueryBuilder {
	qb.rawConditions = append(qb.rawConditions, RawCondition{
		SQL:    field + " BETWEEN ? AND ?",
		Values: []interface{}{start, end},
	})
	return qb
}

// WhereNotBetween 添加NOT BETWEEN查询条件
func (qb *QueryBuilder) WhereNotBetween(field string, start, end interface{}) *QueryBuilder {
	qb.rawConditions = append(qb.rawConditions, RawCondition{
		SQL:    field + " NOT BETWEEN ? AND ?",
		Values: []interface{}{start, end},
	})
	return qb
}

// WhereRaw 添加原始SQL查询条件
func (qb *QueryBuilder) WhereRaw(sql string, values ...interface{}) *QueryBuilder {
	qb.rawConditions = append(qb.rawConditions, RawCondition{
		SQL:    sql,
		Values: values,
	})
	return qb
}

// OrWhere 添加OR查询条件
func (qb *QueryBuilder) OrWhere(field string, value interface{}) *QueryBuilder {
	orCondition := map[string]interface{}{field: value}
	qb.orConditions = append(qb.orConditions, orCondition)
	return qb
}

// OrWhereIn 添加OR IN查询条件
func (qb *QueryBuilder) OrWhereIn(field string, values []interface{}) *QueryBuilder {
	orCondition := map[string]interface{}{field + " IN": values}
	qb.orConditions = append(qb.orConditions, orCondition)
	return qb
}

// OrWhereLike 添加OR LIKE查询条件
func (qb *QueryBuilder) OrWhereLike(field string, pattern string) *QueryBuilder {
	orCondition := map[string]interface{}{field + " LIKE": pattern}
	qb.orConditions = append(qb.orConditions, orCondition)
	return qb
}

// OrWhereNull 添加OR IS NULL查询条件
func (qb *QueryBuilder) OrWhereNull(field string) *QueryBuilder {
	// 使用特殊标记表示这是一个 NULL 条件
	orCondition := map[string]interface{}{field + " IS NULL": nil}
	qb.orConditions = append(qb.orConditions, orCondition)
	return qb
}

// OrWhereNotNull 添加OR IS NOT NULL查询条件
func (qb *QueryBuilder) OrWhereNotNull(field string) *QueryBuilder {
	// 使用特殊标记表示这是一个 NOT NULL 条件
	orCondition := map[string]interface{}{field + " IS NOT NULL": nil}
	qb.orConditions = append(qb.orConditions, orCondition)
	return qb
}

// OrWhereBetween 添加OR BETWEEN查询条件
func (qb *QueryBuilder) OrWhereBetween(field string, start, end interface{}) *QueryBuilder {
	orCondition := map[string]interface{}{field + " BETWEEN": []interface{}{start, end}}
	qb.orConditions = append(qb.orConditions, orCondition)
	return qb
}

// OrderBy 添加排序
func (qb *QueryBuilder) OrderBy(field string) *QueryBuilder {
	qb.orderBy = append(qb.orderBy, field)
	return qb
}

// OrderByDesc 添加降序排序
func (qb *QueryBuilder) OrderByDesc(field string) *QueryBuilder {
	qb.orderBy = append(qb.orderBy, field+" DESC")
	return qb
}

// GroupBy 添加分组
func (qb *QueryBuilder) GroupBy(fields ...string) *QueryBuilder {
	qb.groupBy = append(qb.groupBy, fields...)
	return qb
}

// Limit 设置限制数量
func (qb *QueryBuilder) Limit(limit int) *QueryBuilder {
	qb.limit = limit
	return qb
}

// Offset 设置偏移量
func (qb *QueryBuilder) Offset(offset int) *QueryBuilder {
	qb.offset = offset
	return qb
}

// Select 选择字段
func (qb *QueryBuilder) Select(cols ...string) *QueryBuilder {
	qb.selectCols = cols
	return qb
}

// WithCache 启用缓存
func (qb *QueryBuilder) WithCache(args ...interface{}) *QueryBuilder {
	if len(args) == 0 {
		return qb
	}

	// 解析第一个参数
	switch v := args[0].(type) {
	case bool:
		// WithCache(true) 或 WithCache(false)
		qb.useCache = v
		if v {
			qb.cacheKey = "" // 空字符串表示自动生成
		}
	case string:
		// WithCache("key") 或 WithCache("key", ttl)
		qb.useCache = true
		qb.cacheKey = v
	default:
		// 不支持的类型，不启用缓存
		return qb
	}

	// 解析第二个参数（过期时间）
	if len(args) > 1 {
		if ttl, ok := args[1].(time.Duration); ok {
			qb.cacheTTL = ttl
		}
	} else {
		// 使用默认过期时间，根据当前缓存类型选择合适的TTL
		if qb.tableOp != nil && qb.tableOp.client != nil && qb.tableOp.client.config != nil {
			switch qb.tableOp.client.config.CacheType {
			case CacheTypeRedis:
				if qb.tableOp.client.config.RedisCacheTTL > 0 {
					qb.cacheTTL = qb.tableOp.client.config.RedisCacheTTL
				} else {
					qb.cacheTTL = qb.tableOp.client.config.CacheTTL
				}
			case CacheTypeMemory:
				if qb.tableOp.client.config.MemoryCacheTTL > 0 {
					qb.cacheTTL = qb.tableOp.client.config.MemoryCacheTTL
				} else {
					qb.cacheTTL = qb.tableOp.client.config.CacheTTL
				}
			default:
				// 默认情况下，如果有Redis配置则使用Redis TTL，否则使用通用TTL
				if qb.tableOp.client.config.RedisCacheTTL > 0 {
					qb.cacheTTL = qb.tableOp.client.config.RedisCacheTTL
				} else {
					qb.cacheTTL = qb.tableOp.client.config.CacheTTL
				}
			}
		} else {
			qb.cacheTTL = time.Minute * 5 // 兜底默认值
		}
	}

	return qb
}

// WithCacheType 设置缓存类型
func (qb *QueryBuilder) WithCacheType(cacheType CacheType) *QueryBuilder {
	qb.cacheType = cacheType
	return qb
}

// WithContext 设置上下文
func (qb *QueryBuilder) WithContext(ctx context.Context) *QueryBuilder {
	qb.context = ctx
	return qb
}

// Page 设置分页
func (qb *QueryBuilder) Page(page, pageSize int) *QueryBuilder {
	qb.limit = pageSize
	qb.offset = (page - 1) * pageSize
	return qb
}

// Find 查找记录
func (qb *QueryBuilder) Find(dest interface{}) error {
	if qb == nil || qb.tableOp == nil || qb.tableOp.db == nil {
		return fmt.Errorf("数据库连接未初始化")
	}

	options := &QueryOptions{
		TableName:     qb.tableOp.tableName,
		Conditions:    qb.conditions,
		OrConditions:  qb.orConditions,
		RawConditions: qb.rawConditions,
		OrderBy:       qb.orderBy,
		GroupBy:       qb.groupBy,
		Limit:         qb.limit,
		Offset:        qb.offset,
		Select:        qb.selectCols,
		UseCache:      qb.useCache,
		CacheType:     qb.cacheType,
		CacheKey:      qb.cacheKey,
		CacheTTL:      qb.cacheTTL,
		Context:       qb.context,
	}
	return qb.tableOp.Find(dest, options)
}

// FindOne 查找单条记录
func (qb *QueryBuilder) FindOne(dest interface{}) error {
	if qb == nil || qb.tableOp == nil || qb.tableOp.db == nil {
		return fmt.Errorf("数据库连接未初始化")
	}

	options := &QueryOptions{
		TableName:     qb.tableOp.tableName,
		Conditions:    qb.conditions,
		OrConditions:  qb.orConditions,
		RawConditions: qb.rawConditions,
		OrderBy:       qb.orderBy,
		GroupBy:       qb.groupBy,
		Limit:         1,
		Offset:        qb.offset,
		Select:        qb.selectCols,
		UseCache:      qb.useCache,
		CacheType:     qb.cacheType,
		CacheKey:      qb.cacheKey,
		CacheTTL:      qb.cacheTTL,
		Context:       qb.context,
	}
	return qb.tableOp.FindOne(dest, options)
}

// Count 计数记录
func (qb *QueryBuilder) Count() (int64, error) {
	if qb == nil || qb.tableOp == nil || qb.tableOp.db == nil {
		return 0, fmt.Errorf("数据库连接未初始化")
	}

	options := &QueryOptions{
		TableName:     qb.tableOp.tableName,
		Conditions:    qb.conditions,
		OrConditions:  qb.orConditions,
		RawConditions: qb.rawConditions,
		UseCache:      qb.useCache,
		CacheType:     qb.cacheType,
		CacheKey:      qb.cacheKey,
		CacheTTL:      qb.cacheTTL,
		Context:       qb.context,
	}
	return qb.tableOp.Count(options)
}

// Exists 检查记录是否存在
func (qb *QueryBuilder) Exists() (bool, error) {
	count, err := qb.Count()
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// Update 更新记录
func (qb *QueryBuilder) Update(updates interface{}) error {
	if qb == nil || qb.tableOp == nil || qb.tableOp.db == nil {
		return fmt.Errorf("数据库连接未初始化")
	}

	options := &UpdateOptions{
		TableName:  qb.tableOp.tableName,
		Conditions: qb.conditions,
		Context:    qb.context,
		ClearCache: true,
	}
	return qb.tableOp.Update(updates, options)
}

// Delete 删除记录
func (qb *QueryBuilder) Delete(softDelete ...bool) error {
	if qb == nil || qb.tableOp == nil || qb.tableOp.db == nil {
		return fmt.Errorf("数据库连接未初始化")
	}

	soft := true
	if len(softDelete) > 0 {
		soft = softDelete[0]
	}

	options := &DeleteOptions{
		TableName:  qb.tableOp.tableName,
		Conditions: qb.conditions,
		Context:    qb.context,
		SoftDelete: soft,
		ClearCache: true,
	}
	return qb.tableOp.Delete(options)
}

// Paginate 分页查询
func (qb *QueryBuilder) Paginate(page, pageSize int, dest interface{}) (*PaginationResult, error) {
	if qb == nil || qb.tableOp == nil || qb.tableOp.db == nil {
		return nil, fmt.Errorf("数据库连接未初始化")
	}

	// 获取总数
	total, err := qb.Count()
	if err != nil {
		return nil, fmt.Errorf("获取总数失败: %w", err)
	}

	// 计算分页信息
	totalPages := int((total + int64(pageSize) - 1) / int64(pageSize))

	// 设置分页参数
	qb.Page(page, pageSize)

	// 查询数据
	err = qb.Find(dest)
	if err != nil {
		return nil, fmt.Errorf("查询数据失败: %w", err)
	}

	return &PaginationResult{
		Total:      total,
		Page:       page,
		PageSize:   pageSize,
		TotalPages: totalPages,
		Data:       dest,
	}, nil
}

// Clone 克隆查询构建器（优化版本）
func (qb *QueryBuilder) Clone() *QueryBuilder {
	// 预分配适当容量，减少重新分配
	newQB := &QueryBuilder{
		tableOp:       qb.tableOp,
		conditions:    make(map[string]interface{}, len(qb.conditions)),
		orConditions:  make([]map[string]interface{}, len(qb.orConditions)),
		rawConditions: make([]RawCondition, len(qb.rawConditions)),
		orderBy:       make([]string, len(qb.orderBy), cap(qb.orderBy)),
		groupBy:       make([]string, len(qb.groupBy), cap(qb.groupBy)),
		selectCols:    make([]string, len(qb.selectCols), cap(qb.selectCols)),
		limit:         qb.limit,
		offset:        qb.offset,
		useCache:      qb.useCache,
		cacheType:     qb.cacheType,
		cacheKey:      qb.cacheKey,
		cacheTTL:      qb.cacheTTL,
		context:       qb.context,
	}

	// 深拷贝 AND 条件
	for k, v := range qb.conditions {
		newQB.conditions[k] = v
	}

	// 深拷贝 OR 条件
	for i, orCond := range qb.orConditions {
		newQB.orConditions[i] = make(map[string]interface{}, len(orCond))
		for k, v := range orCond {
			newQB.orConditions[i][k] = v
		}
	}

	// 深拷贝原始条件
	copy(newQB.rawConditions, qb.rawConditions)

	// 直接拷贝切片内容
	copy(newQB.orderBy, qb.orderBy)
	copy(newQB.groupBy, qb.groupBy)
	copy(newQB.selectCols, qb.selectCols)

	return newQB
}
